//
// Copyright (C) Robert Bosch GmbH
// Date: June 2012
// Author: CR/RTC2-AP Jim Lundberg

#include "vocon3200_base.h"
#include "vocon3200_asr.h"
#include "vocon3200_sem.h"
#include "vocon3200_pron.h"
#include "vocon3200_gram2.h"
#include "vocon3200_sse.h"
#include "vocon_ext_heap.h"
#include "vocon_ext_stream.h"
#include "vocon_ext_audioin.h"
#include "vocon_ext_asr2sem.h"

#include "SpeechRecognizer.h"

#define SEMPROCFEATURE_HYPOTHESIS_CONFIDENCE_NAME "confidence"
#define SEMPROCFEATURE_WORD_CONFIDENCE_NAME "confidence"
#define SEMPROCFEATURE_WORD_BEGINTIME_NAME "beginTime"
#define SEMPROCFEATURE_WORD_ENDTIME_NAME "endTime"

#define SAMPLE_FREQ 16000
#define SOUND_BUF_SIZE 3840
#define TRANSCRIPTION_NUMBER 1
#define SIMPLEFORMAT 1

typedef struct RECOG_OBJECTS_S {
  void             *pHeapInst;             /* Pointer to the heap. */
  LH_COMPONENT      hCompBase;             /* Handle to the base component. */
  LH_COMPONENT      hCompAsr;              /* Handle to the ASR component. */
  LH_COMPONENT      hCompPron;             /* Handle to the pronunciation component. */
  LH_COMPONENT	    hCompG2P;
  LH_OBJECT         hAcMod;                /* Handle to the AcMod object. */
  LH_OBJECT         hCtx[3];               /* Handle to the Context object. */
  LH_OBJECT         *phListCtx;            /* Handels to the array of listCtx. */
  LH_OBJECT         *phFieldCtx;           /* Handels to the array of fieldCtx. */
  LH_OBJECT         hAudioType;            /* Handle to the AudioType object. */
  LH_OBJECT         hAudioSource;          /* Handle to the Audio Source object. */
  LH_OBJECT         hFx;                   /* Handle to the Feature Extractor Object. */
  LH_OBJECT         hRec;                  /* Handle to the Recognizer Object. */
  LH_OBJECT         h_lex;
  LH_OBJECT         h_ddg2p;
  LH_OBJECT         h_dct;
  unsigned long     sampleFreq;            /* Sampling frequency. */
  unsigned long     audioSourceFrameSizeInBytes; /* Size of one frame used by the AudioSource object. */
} RECOG_OBJECTS;

typedef struct vocon3200Sem_S {
  LH_COMPONENT         h_csem[3];
  LH_OBJECT            h_semproc[3];
  LH_HEAP_INTERFACE    heap_itf[3];
  void*                heap_inst[3];
} VOCON3200SEM;

typedef struct NBESTENTRY_WORD_S {
  const char* word;
  unsigned long confidence;
  unsigned long begin_time;
  unsigned long end_time;
} NBESTENTRY_WORD;

typedef struct NBESTENTRY_S {
  NBESTENTRY_WORD* p_words;
  unsigned long nbr_of_words;
  unsigned long confidence;
} NBESTENTRY;

typedef struct VOCON3200ASR_S {
  LH_ERROR             e_last_vocon3200;
  ST_ERROR             e_last_stream;
  PH_ERROR             e_last_heap;
  LH_COMPONENT         h_casr;
  LH_HEAP_INTERFACE    heap_itf;
  void*                heap_inst;
  LH_OBJECT            h_acmod;
  LH_OBJECT            h_audio_source;
  LH_OBJECT            h_fx;
  LH_OBJECT            h_jumpback_buffer;
  LH_OBJECT            h_rec;
  LH_OBJECT            h_ctx;
  LH_OBJECT            h_spelltree;
  LH_OBJECT            h_spelleng;
  LH_OBJECT            h_usw;
  int                  i_resultdetaillevel;
  LH_TIME              last_event_time_ms;
} VOCON3200ASR;

class ConfigCtx {
public:
	std::string id;
	std::string type;
	std::string semId;
	std::string fileName;
	std::string slotLoadingType;
	std::string idMappingFileName;
	std::string grammarName;
	bool enableExportSlotContext;
	unsigned long ctxParamAcc;
	unsigned long ctxParamInitB;
	std::map<std::string, std::string> slot2FileName;
	std::map<std::string, std::string> field2FileName;
};

class ConfigSem {
public:
	std::string semId;
	std::string fileName;
};

class ConfigData {
public:
	std::string acmFileName;
	std::string ddg2pFileName;
	std::string dictFileName;
	std::string startWaveFileName;
	std::string endWaveFileName;
	int nBest;
	int numberOfContexts;
	int numberOfSem;
	ConfigCtx cfgCtx[3];
	ConfigSem cfgSem[3];
	std::map<std::string, int> ctxID2Index;
	std::map<std::string, int> semID2Index;
};

class Vocon45 : public SpeechRecognizer {
public:
	Vocon45() : SpeechRecognizer(SR_ENGINE_VOCON45)
	{
		pResult = NULL;
		endWV = 0;
		startWV = 0;
	};
	virtual ~Vocon45() { destory(); };

	bool destory();
	virtual bool initialize(void);
	virtual SRError recFromFile(const char *wavFileName, SRNLUResult *result);
	virtual SRError recFromMic(int sessionID, const char *logWAVFileName, SRNLUResult *result);
	virtual bool stopRecording(int sessionID);
	
	bool updateSlots(const char *slotName, const char *slotValues);//slotValues = abc,xyz,mno,...
	bool exportListContext(const char *slotName, const char *slotFileName);
	bool activateRule(const char *slotNames);

	ConfigData cfgData;
	RECOG_OBJECTS   recObjs;
	VOCON3200SEM	voconSem;
	
private:
	bool initObjects();
	bool initRecoginer();
	bool initContexts();
	bool initHostContexts(int i);
	bool initListContexts(int iCtx, int iList, const char *slotNM, const char *slotFN);
	bool initFieldContexts(int iCtx, int iField, const char *fieldNM, const char *fieldFN);
	bool initSem();
	void closeAll();
	bool handleEvent (LH_AUDIOCHAIN_EVENT_INFO iEvent, int *pbStopAudioIn, SRError &error);

	SRNLUResult *pResult;

	char *startWV;
	char *endWV;
};
